﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;

namespace Qreed.Windows.ComponentModel
{
    public class PropertyBagReflected : PropertyBag
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyBagReflected"/> class.
        /// </summary>
        /// <param name="target">The target.</param>
        public PropertyBagReflected(object target) : base()
        {
            if (target == null)
                throw (new ArgumentNullException("target", "Can't create a property bag of a null target."));

            _target = target;
            ReflectTarget();
        }

        private void ReflectTarget()
        {
            Type t = _target.GetType();

            PropertyInfo[] pis = t.GetProperties();

            foreach (PropertyInfo pi in pis)
            {
                Items.Add(PropertyBagItem.FromPropertyInfo(pi, _target));   
            }
        }

        private object _target;
        /// <summary>
        /// Gets the target object that this property bag is reflecting.
        /// </summary>
        /// <value>The target object.</value>
        [Browsable(false)]
        public object Target
        {
            get { return this._target; }
        }

        /// <summary>
        /// Raises the <see cref="E:SetValue"/> event.
        /// </summary>
        /// <param name="e">The <see cref="Qreed.Windows.ComponentModel.PropertyBagEventArgs"/> instance containing the event data.</param>
        public override void OnSetValue(PropertyBagEventArgs e)
        {
            base.OnSetValue(e);

            Type t = _target.GetType();

            PropertyInfo pi = t.GetProperty(e.Item.Name);

            if (pi == null)
                throw (new ApplicationException("Failed getting property info for " + e.Item.Name));

            pi.SetValue(Target, e.Value, null);
        }
    }
}
